package com.evl.vehicleSchedule.service.impl;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.evl.common.constant.Const;
import com.evl.common.persistence.dao.ScheduleStationMapper;
import com.evl.common.persistence.dao.StationMapper;
import com.evl.common.persistence.dao.StationSeatRMapper;
import com.evl.common.persistence.dao.TicketRemainderMapper;
import com.evl.common.persistence.dao.TrainSeatMapper;
import com.evl.common.persistence.dao.TrainSeatScheduleMapper;
import com.evl.common.persistence.dao.VehicleMapper;
import com.evl.common.persistence.dao.VehicleScheduleMapper;
import com.evl.common.persistence.model.ScheduleStation;
import com.evl.common.persistence.model.Station;
import com.evl.common.persistence.model.StationSeatR;
import com.evl.common.persistence.model.TicketRemainder;
import com.evl.common.persistence.model.TrainSeat;
import com.evl.common.persistence.model.TrainSeatSchedule;
import com.evl.common.persistence.model.Vehicle;
import com.evl.common.persistence.model.VehicleSchedule;
import com.evl.dictionaryConfig.DictConfig;
import com.evl.dictionaryConfig.DictConst;
import com.evl.utils.Combine;
import com.evl.utils.DateUtils;
import com.evl.utils.JsonUtils;
import com.evl.utils.ListSortUtil;
import com.evl.vehicleSchedule.dao.VehicleScheduleDao;
import com.evl.vehicleSchedule.service.IVehicleScheduleService;
import com.evl.vehicleSchedule.vo.ScheduleVo;

/**
 * <p>
 * 调度车辆表 服务实现类
 * </p>
 *
 * @author yangliwei
 * @since 2017-06-16
 */
@Service
public class VehicleScheduleServiceImpl  implements IVehicleScheduleService {

	@Resource
	VehicleScheduleDao vehicleScheduleDao;
	
	@Resource
	VehicleMapper vehicleMapper;
	@Resource
	StationMapper stationMapper;
	@Resource
	TrainSeatMapper trainSeatMapper;
	@Resource
    VehicleScheduleMapper vehicleScheduleMapper;
	@Resource
	ScheduleStationMapper scheduleStationMapper;
	@Resource
	TrainSeatScheduleMapper trainSeatScheduleMapper;
	@Resource
	StationSeatRMapper stationSeatRMapper;
	@Resource
	TicketRemainderMapper ticketRemainderMapper;
	
	
	@Override
	public ScheduleVo findScheduleDetail(Integer vehicleScheduleId) throws Exception {
		ScheduleVo scheduleVo = vehicleScheduleDao.selectDetailById(vehicleScheduleId);
		
		List<ScheduleStation> ssList= vehicleScheduleDao.selectScheduleStationList(vehicleScheduleId);
		List<TrainSeatSchedule> tssList= vehicleScheduleDao.selectSeatScheduleList(vehicleScheduleId);
		
		scheduleVo.setScheduleStationList(ssList);
		scheduleVo.setScheduleSeatList(tssList);
		
		return scheduleVo;
	}

	
	/**
	 * 使用事务处理
	 */
	@Override
	@Transactional 
	public void insertVehicleSchedule(ScheduleVo scheduleVo) throws Exception {
		
		List<String> goList = new ArrayList<String>(); //去程日期list
    	try {
    		Date standardDate = new Date();
    		try {
    			standardDate = DateUtils.getDateByTimeDD(DictConfig.getKey(DictConst.schedule_standard_date)); //以此日期作为去程(西宁至德令哈 )日期的基准，返程+1
    		} catch (ParseException e) {
    			e.printStackTrace();
    		}
    		
    		//计算调度日期与基准日期的天数差
    		int days =DateUtils.daysBetween(standardDate,DateUtils.getDateByTimeDD(scheduleVo.getBeginDate()));
    		if(days < 0){
    			scheduleVo.setBeginDate(DateUtils.getSpecifyDate(standardDate, DateUtils.FORMAT_YYYY_MM_DD));
    		}
    		if(days % 2 != 0){ //去程（隔日发车）
    			Date beginDate =DateUtils.getPreviousOrNextDaysOfDate(DateUtils.getDateByTimeDD(scheduleVo.getBeginDate()),1);
    			scheduleVo.setBeginDate(DateUtils.getSpecifyDate(beginDate, DateUtils.FORMAT_YYYY_MM_DD));
    		}
    		
    		goList = DateUtils.getAreaDayTimeInterval(scheduleVo.getBeginDate(), scheduleVo.getEndDate(), scheduleVo.getInterval());
		} catch (Exception e1) {
			e1.printStackTrace();
			//不处理
		}  
    	
    	//获取调度车次数组
    	String [] vehicleIds = new String[]{};
    	vehicleIds = (String[]) JsonUtils.fromJson(scheduleVo.getVehicleIds(), vehicleIds.getClass());
    	
		for (String vehicleId : vehicleIds){
			
			//获取模板数据
			Vehicle vehicle = vehicleMapper.selectById(vehicleId);
			
			//定义调度车次list
			List<VehicleSchedule> schedulelist = new ArrayList<VehicleSchedule>();
			
			//批量生成去程的车次信息
			for ( String goDate : goList){
				
				VehicleSchedule vSchedule = vehicleScheduleDao.getVehicleScheduleByTime(vehicle.getVehicleNo(), goDate);
				if(vSchedule != null){//如果已经存在跳过
					continue;
				}
				
				vSchedule =new VehicleSchedule();
				
				vSchedule.setVehicleType(vehicle.getVehicleType());//车辆类型
				vSchedule.setVehicleNo(vehicle.getVehicleNo());//车次
				vSchedule.setDepartTime(DateUtils.getDateByTimeMM(goDate+" "+vehicle.getDepartTime()));//去程发车时间
				vSchedule.setCostTime(vehicle.getCostTime());//耗时
				vSchedule.setArrTime(DateUtils.getPreviousOrNextMinutesOfDate(vSchedule.getDepartTime(), Integer.parseInt(vSchedule.getCostTime())));//去程到达时间
				vSchedule.setDeparture(vehicle.getDeparture());//始发站
				vSchedule.setTerminus(vehicle.getTerminus());//终点站
				
				schedulelist.add(vSchedule);
			}
			
			//批量生成调度车次（车次、车站、座位、车站座位关系、余票）
			createSchedules(vehicle, schedulelist);
		}
		
	}

	/**
	 * 批量生成调度车次（车次、车站、座位、车站座位关系、余票）
	 * @param vehicleList
	 * @param schedulelist
	 */
	@Override
	public void createSchedules(Vehicle vehicle, List<VehicleSchedule> schedulelist){
		if(vehicle == null || vehicle.getId() ==null){
			return;
		}
		
		if(schedulelist == null || schedulelist.size()==0){
			return;
		}

		List<Station> goStationList = stationMapper.selectStationByWhere(vehicle.getId()); //根据车辆获取车站list
    	
    	List<TrainSeat> seatList = trainSeatMapper.selectTrainSeatsByWhere(vehicle.getId()); //根据车辆获取座位list
		
		//保存调度车辆信息
    	vehicleScheduleDao.batchSaveSchedules(schedulelist);
    	
    	
    	List<ScheduleStation> scheduleStationList =new ArrayList<ScheduleStation>();
    	List<TrainSeatSchedule> trainSeatScheduleList = new ArrayList<TrainSeatSchedule>();
    	
    	for(VehicleSchedule vs : schedulelist){
    		
    		//封装调度车站信息--去程
			disposeDcheduleStation(vs,goStationList,scheduleStationList);
    		
    		//封装调度座位信息
    		for(TrainSeat seat : seatList){
    			TrainSeatSchedule trainSeatSchedule = new TrainSeatSchedule();
    			
    			trainSeatSchedule.setStaId(vs.getId());//调度车辆id
    			trainSeatSchedule.setCarriageNo(seat.getCarriageNo());
    			trainSeatSchedule.setSeatNo(seat.getSeatNo());
    			trainSeatSchedule.setSeatType(seat.getSeatType());
    			
    			trainSeatScheduleList.add(trainSeatSchedule);
    		}
    		   
    	}
    	
    	if(scheduleStationList ==null || scheduleStationList.size()==0){
    		return;
    	}
    	
    	if(trainSeatScheduleList ==null || trainSeatScheduleList.size()==0){
    		return;
    	}
    
    	//批量保存调度车站、调度座位
    	vehicleScheduleDao.batchSaveScheduleStations(scheduleStationList);
    	vehicleScheduleDao.batchSaveTrainSeatSchedules(trainSeatScheduleList);
    	
    	List<TicketRemainder> ticketRemainderList = new ArrayList<TicketRemainder>();
    	for(VehicleSchedule vs : schedulelist){
    		
    		List<ScheduleStation> data = new ArrayList<ScheduleStation>();
    		List<String[]> dataArrList = new ArrayList<String[]>();
    		
    		for(ScheduleStation scheduleS : scheduleStationList){
    			if(vs.getId().equals(scheduleS.getStaId())){
    				data.add(scheduleS);
    			}
    		}
    		
    		ListSortUtil<ScheduleStation> ttList = new ListSortUtil<ScheduleStation>();
    		ttList.sort(data, "seq", "ASC");

    		List<String> stationData = new ArrayList<String>();
    		stationData.add(vs.getDeparture());
    		stationData.add(vs.getTerminus());
    		
    		//穷举所有的乘坐路线信息
    		dataArrList = Combine.combineAll(stationData);
    		
    		//定义余票数
    		int ticketCount =0;
    		for(TrainSeatSchedule tss : trainSeatScheduleList){
    			if(tss.getStaId().equals(vs.getId())){
    				ticketCount++;
    			}
    		}
    		
    		//初始化席别余票数
    		Map<String,Integer> seatMap = new HashMap<String, Integer>();
    		//seatMap.put(Const.SEAT_TOURIST, 0);
    		//seatMap.put(Const.SEAT_SOFT, 0);
    		for(TrainSeatSchedule tss : trainSeatScheduleList){
    			if(tss.getStaId().equals(vs.getId())){
    				seatMap.put(tss.getSeatType(), seatMap.get(tss.getSeatType())==null?1:seatMap.get(tss.getSeatType())+1);
    			}
    		}
    		
    		//封装余票信息
    		for (String [] dataStr : dataArrList){
    			
    			TicketRemainder ticketRemainder = new TicketRemainder();
    			ticketRemainder.setStaId(vs.getId());
    			ticketRemainder.setTrainNo(vs.getVehicleNo());//调度车辆的车次
    			ticketRemainder.setTicketCount(ticketCount);//余票总数
    			ticketRemainder.setSeatDetail(JsonUtils.toJson(seatMap));
    			ticketRemainder.setDeparture(dataStr[0]);//线路起始站
    			ticketRemainder.setArrive(dataStr[dataStr.length-1]);//线路到达站
    			for(ScheduleStation sstation :data){
    				if(sstation.getStationName().equals(dataStr[0])){
    					ticketRemainder.setStartTime(sstation.getStartTime());
    				}else if (sstation.getStationName().equals(dataStr[dataStr.length-1])){
    					ticketRemainder.setArrTime(sstation.getArrTime());
    				}
    			}
    			ticketRemainder.setStationOrder(JsonUtils.toJson(dataStr));
    			
    			ticketRemainderList.add(ticketRemainder);
    			
    		}
    		if(ticketRemainderList.size() >= 30000){//达到3万条就保存，防止内存溢出
    			//批量保存调度余票
    			vehicleScheduleDao.batchSaveTicketRemainders(ticketRemainderList);
    			ticketRemainderList =new ArrayList<TicketRemainder>();
    		}
    	}
    	if(ticketRemainderList.size() > 0){
    		//批量保存调度余票
    		vehicleScheduleDao.batchSaveTicketRemainders(ticketRemainderList);
    	}
    	
    	List<StationSeatR> stationSeatRList = new ArrayList<StationSeatR>();
    	//封装调度车站与座位关系信息 
		for (ScheduleStation scheduleStation : scheduleStationList){
			for (TrainSeatSchedule trainSeatSchedule : trainSeatScheduleList){
				if(scheduleStation.getStaId().equals(trainSeatSchedule.getStaId())){

					StationSeatR stationSeatR = new StationSeatR();
					stationSeatR.setStationId(scheduleStation.getId());
					stationSeatR.setSeatId(trainSeatSchedule.getId());
					stationSeatR.setSeatStatus(Const.SEAT_CHOOSABLE);//0.可选 1已锁定
					
					stationSeatRList.add(stationSeatR);
					
					if(stationSeatRList.size()>=30000){//达到3万条就保存，防止内存溢出
						//批量保存车站与座位关系
						vehicleScheduleDao.batchSaveStationSeatRs(stationSeatRList);
						stationSeatRList =new ArrayList<StationSeatR>();
					}
				}
				
			}
		}
		if(stationSeatRList.size()>0){
			//批量保存车站与座位关系
			vehicleScheduleDao.batchSaveStationSeatRs(stationSeatRList);
		}
	}


	private void disposeDcheduleStation(VehicleSchedule vs, List<Station> stationList,
			List<ScheduleStation> scheduleStationList) {
		
		ScheduleStation parentStation = new ScheduleStation();
		
		//封装调度车站信息
		for(Station station : stationList){
			
			ScheduleStation scheduleStation =new ScheduleStation();
			scheduleStation.setStationId(station.getId());//引用的车站id
			scheduleStation.setStaId(vs.getId());//调度车辆id
			scheduleStation.setSeq(station.getSeq());
			scheduleStation.setStationName(station.getStationName());
			scheduleStation.setStopTime(station.getStopTime());
			scheduleStation.setCostTime(station.getCostTime());
			
			if(station.getStationName().equals(vs.getDeparture())){//判断为始发站
				scheduleStation.setStartTime(vs.getDepartTime());
				scheduleStation.setArrTime(null);
			}else if(station.getStationName().equals(vs.getTerminus())){//判断为终点站
				scheduleStation.setStartTime(null);
				scheduleStation.setArrTime(DateUtils.getNextMinutesDateTime(parentStation.getStartTime(), Integer.parseInt(parentStation.getCostTime())));
			}else{
				scheduleStation.setArrTime(DateUtils.getNextMinutesDateTime(parentStation.getStartTime(), Integer.parseInt(parentStation.getCostTime())));
				scheduleStation.setStartTime(DateUtils.getNextMinutesDateTime(scheduleStation.getArrTime(), Integer.parseInt(scheduleStation.getStopTime())));
			}
			
			parentStation = scheduleStation;
			
			scheduleStationList.add(scheduleStation);
			
		}
		
	}


	@Override
	@Transactional
	public Map<String, Object> deleteVehicleSchedule(Integer vehicleScheduleId) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		
		try {
			//查询调度车次对应的车站列表
			List<ScheduleStation> ssList = scheduleStationMapper.selectScheduleStations(vehicleScheduleId);//DONE
			//第一步
			ticketRemainderMapper.deleteByStaId(vehicleScheduleId);//DONE
			//第二步
			stationSeatRMapper.deleteByStationIds(ssList);//DONE
			//第三步
			scheduleStationMapper.deleteByStaId(vehicleScheduleId);//DONE
			//第四步
			trainSeatScheduleMapper.deleteByStaId(vehicleScheduleId);
			//最后一步
			vehicleScheduleMapper.deleteById(vehicleScheduleId);
			resultMap.put("result","success");
			resultMap.put("msg", "删除调度车次成功");
		} catch (Exception e) {
			resultMap.put("result","fail");
			resultMap.put("msg", "删除调度车次失败");
		}
		return resultMap;
	}
	
	
}
